<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.17"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>CANopenNode: Critical sections</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
  $(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname">CANopenNode
   </div>
  </td>
   <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
</td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.17 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('group__CO__critical__sections.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="summary">
<a href="#define-members">Macros</a>  </div>
  <div class="headertitle">
<div class="title">Critical sections<div class="ingroups"><a class="el" href="group__CO__CANopen__301.html">CANopen_301</a> &raquo; <a class="el" href="group__CO__driver.html">Driver</a></div></div>  </div>
</div><!--header-->
<div class="contents">

<p>CANopenNode is designed to run in different threads, as described in <a href="index.html">README.md</a>. Threads are implemented differently in different systems. In microcontrollers threads are interrupts with different priorities, for example. It is necessary to protect sections, where different threads access to the same resource. In simple systems interrupts or scheduler may be temporary disabled between access to the shared resource. Otherwise mutexes or semaphores can be used.  
<a href="#details">More...</a></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="define-members"></a>
Macros</h2></td></tr>
<tr class="memitem:ga7566ee901bbf1a0d76d771d72d2f826f"><td class="memItemLeft" align="right" valign="top"><a id="ga7566ee901bbf1a0d76d771d72d2f826f"></a>
#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__CO__critical__sections.html#ga7566ee901bbf1a0d76d771d72d2f826f">CO_LOCK_CAN_SEND</a>()</td></tr>
<tr class="memdesc:ga7566ee901bbf1a0d76d771d72d2f826f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Lock critical section in <a class="el" href="group__CO__driver.html#ga4664a9f5d547cb0605a9e929fb079f2e" title="Send CAN message.">CO_CANsend()</a> <br /></td></tr>
<tr class="separator:ga7566ee901bbf1a0d76d771d72d2f826f"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga511a5a0bf905c2207d5c9e26d35fe3cc"><td class="memItemLeft" align="right" valign="top"><a id="ga511a5a0bf905c2207d5c9e26d35fe3cc"></a>
#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__CO__critical__sections.html#ga511a5a0bf905c2207d5c9e26d35fe3cc">CO_UNLOCK_CAN_SEND</a>()</td></tr>
<tr class="memdesc:ga511a5a0bf905c2207d5c9e26d35fe3cc"><td class="mdescLeft">&#160;</td><td class="mdescRight">Unlock critical section in <a class="el" href="group__CO__driver.html#ga4664a9f5d547cb0605a9e929fb079f2e" title="Send CAN message.">CO_CANsend()</a> <br /></td></tr>
<tr class="separator:ga511a5a0bf905c2207d5c9e26d35fe3cc"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga3052a84235f56d535a14705e0cfda799"><td class="memItemLeft" align="right" valign="top"><a id="ga3052a84235f56d535a14705e0cfda799"></a>
#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__CO__critical__sections.html#ga3052a84235f56d535a14705e0cfda799">CO_LOCK_EMCY</a>()</td></tr>
<tr class="memdesc:ga3052a84235f56d535a14705e0cfda799"><td class="mdescLeft">&#160;</td><td class="mdescRight">Lock critical section in <a class="el" href="group__CO__Emergency.html#gab66d4a6daa5f7492704b56a46b135f71" title="Report error condition, for description of parameters see CO_error.">CO_errorReport()</a> or <a class="el" href="group__CO__Emergency.html#ga24e2a9311cf704ec6ed43b0ea730c4a3" title="Reset error condition, for description of parameters see CO_error.">CO_errorReset()</a> <br /></td></tr>
<tr class="separator:ga3052a84235f56d535a14705e0cfda799"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga720a798f2bf7fe20d9c95a212b4df417"><td class="memItemLeft" align="right" valign="top"><a id="ga720a798f2bf7fe20d9c95a212b4df417"></a>
#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__CO__critical__sections.html#ga720a798f2bf7fe20d9c95a212b4df417">CO_UNLOCK_EMCY</a>()</td></tr>
<tr class="memdesc:ga720a798f2bf7fe20d9c95a212b4df417"><td class="mdescLeft">&#160;</td><td class="mdescRight">Unlock critical section in <a class="el" href="group__CO__Emergency.html#gab66d4a6daa5f7492704b56a46b135f71" title="Report error condition, for description of parameters see CO_error.">CO_errorReport()</a> or <a class="el" href="group__CO__Emergency.html#ga24e2a9311cf704ec6ed43b0ea730c4a3" title="Reset error condition, for description of parameters see CO_error.">CO_errorReset()</a> <br /></td></tr>
<tr class="separator:ga720a798f2bf7fe20d9c95a212b4df417"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga3850830931ced2bd3d7e15821572bbcc"><td class="memItemLeft" align="right" valign="top"><a id="ga3850830931ced2bd3d7e15821572bbcc"></a>
#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__CO__critical__sections.html#ga3850830931ced2bd3d7e15821572bbcc">CO_LOCK_OD</a>()</td></tr>
<tr class="memdesc:ga3850830931ced2bd3d7e15821572bbcc"><td class="mdescLeft">&#160;</td><td class="mdescRight">Lock critical section when accessing Object Dictionary. <br /></td></tr>
<tr class="separator:ga3850830931ced2bd3d7e15821572bbcc"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga2477f5d24fd31a9f4052cf451b87809f"><td class="memItemLeft" align="right" valign="top"><a id="ga2477f5d24fd31a9f4052cf451b87809f"></a>
#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__CO__critical__sections.html#ga2477f5d24fd31a9f4052cf451b87809f">CO_UNLOCK_OD</a>()</td></tr>
<tr class="memdesc:ga2477f5d24fd31a9f4052cf451b87809f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Unock critical section when accessing Object Dictionary. <br /></td></tr>
<tr class="separator:ga2477f5d24fd31a9f4052cf451b87809f"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga577a6ebcf246087f084c75d9ae25eeb7"><td class="memItemLeft" align="right" valign="top"><a id="ga577a6ebcf246087f084c75d9ae25eeb7"></a>
#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__CO__critical__sections.html#ga577a6ebcf246087f084c75d9ae25eeb7">CO_FLAG_READ</a>(rxNew)&#160;&#160;&#160;((rxNew) != <a class="el" href="group__CO__dataTypes.html#ga070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>)</td></tr>
<tr class="memdesc:ga577a6ebcf246087f084c75d9ae25eeb7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Check if new message has arrived. <br /></td></tr>
<tr class="separator:ga577a6ebcf246087f084c75d9ae25eeb7"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gac54b5e4f680aa8b0177f0df5d5be2e88"><td class="memItemLeft" align="right" valign="top"><a id="gac54b5e4f680aa8b0177f0df5d5be2e88"></a>
#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__CO__critical__sections.html#gac54b5e4f680aa8b0177f0df5d5be2e88">CO_FLAG_SET</a>(rxNew)&#160;&#160;&#160;{ __sync_synchronize(); rxNew = (void *)1L; }</td></tr>
<tr class="memdesc:gac54b5e4f680aa8b0177f0df5d5be2e88"><td class="mdescLeft">&#160;</td><td class="mdescRight">Set new message flag. <br /></td></tr>
<tr class="separator:gac54b5e4f680aa8b0177f0df5d5be2e88"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga044da4253aeed15c3e0bb7fce13664af"><td class="memItemLeft" align="right" valign="top"><a id="ga044da4253aeed15c3e0bb7fce13664af"></a>
#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__CO__critical__sections.html#ga044da4253aeed15c3e0bb7fce13664af">CO_FLAG_CLEAR</a>(rxNew)&#160;&#160;&#160;{ __sync_synchronize(); rxNew = <a class="el" href="group__CO__dataTypes.html#ga070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>; }</td></tr>
<tr class="memdesc:ga044da4253aeed15c3e0bb7fce13664af"><td class="mdescLeft">&#160;</td><td class="mdescRight">Clear new message flag. <br /></td></tr>
<tr class="separator:ga044da4253aeed15c3e0bb7fce13664af"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<p>CANopenNode is designed to run in different threads, as described in <a href="index.html">README.md</a>. Threads are implemented differently in different systems. In microcontrollers threads are interrupts with different priorities, for example. It is necessary to protect sections, where different threads access to the same resource. In simple systems interrupts or scheduler may be temporary disabled between access to the shared resource. Otherwise mutexes or semaphores can be used. </p>
<h4>Reentrant functions</h4>
<p>Functions <a class="el" href="group__CO__driver.html#ga4664a9f5d547cb0605a9e929fb079f2e" title="Send CAN message.">CO_CANsend()</a> from C_driver.h, <a class="el" href="group__CO__Emergency.html#gab66d4a6daa5f7492704b56a46b135f71" title="Report error condition, for description of parameters see CO_error.">CO_errorReport()</a> from <a class="el" href="CO__Emergency_8h.html" title="CANopen Emergency protocol.">CO_Emergency.h</a> and <a class="el" href="group__CO__Emergency.html#ga24e2a9311cf704ec6ed43b0ea730c4a3" title="Reset error condition, for description of parameters see CO_error.">CO_errorReset()</a> from <a class="el" href="CO__Emergency_8h.html" title="CANopen Emergency protocol.">CO_Emergency.h</a> may be called from different threads. Critical sections must be protected. Either by disabling scheduler or interrupts or by mutexes or semaphores.</p>
<h4>Object Dictionary variables</h4>
<p>In general, there are two threads, which accesses OD variables: mainline and timer. CANopenNode initialization and SDO server runs in mainline. PDOs runs in faster timer thread. Processing of PDOs must not be interrupted by mainline. Mainline thread must protect sections, which accesses the same OD variables as timer thread. This care must also take the application. Note that not all variables are allowed to be mapped to PDOs, so they may not need to be protected. SDO server protects sections with access to OD variables.</p>
<h4>Synchronization functions for CAN receive</h4>
<p>After CAN message is received, it is pre-processed in <a class="el" href="group__CO__CAN__Message__reception.html#ga23168979123a5ca8a87d49307eb2990e" title="CAN receive callback function which pre-processes received CAN message.">CANrx_callback()</a>, which copies some data into appropriate object and at the end sets <b>new_message</b> flag. This flag is then pooled in another thread, which further processes the message. The problem is, that compiler optimization may shuffle memory operations, so it is necessary to ensure, that <b>new_message</b> flag is surely set at the end. It is necessary to use <a href="https://en.wikipedia.org/wiki/Memory_barrier">Memory barrier</a>.</p>
<p>If receive function runs inside IRQ, no further synchronization is needed. Otherwise, some kind of synchronization has to be included. The following example uses GCC builtin memory barrier <code>__sync_synchronize()</code>. More information can be found <a href="https://stackoverflow.com/questions/982129/what-does-sync-synchronize-do#982179">here</a>. </p>
</div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated on Thu Dec 24 2020 14:30:50 for CANopenNode by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.17 </li>
  </ul>
</div>
</body>
</html>
